#include "base_client.hpp"

void BaseClient::Listener::on_data_available(eprosima::fastdds::dds::DataReader* reader)
{
    CommonData response;

    eprosima::fastdds::dds::SampleInfo sample_info;

    reader->take_next_sample(&response, &sample_info);

    if (sample_info.instance_state == eprosima::fastdds::dds::InstanceStateKind::ALIVE_INSTANCE_STATE) {
        if (sample_info.related_sample_identity == this->write_params.sample_identity()) {
            {
                std::unique_lock<std::mutex> lock(this->reception_mutex);
                this->received_replay = true;
                this->response = response.data();
            }
            this->reception_cv.notify_one();    // TODO 理一下这句代码
        }
    }

}

bool BaseClient::init()
{
    // 构造通信参与者
    this->participant_ = eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->create_participant(
        0, eprosima::fastdds::dds::PARTICIPANT_QOS_DEFAULT
    );
    if (this->participant_ == nullptr) {
        return false;
    }

    // 注册数据类型，并将使用的参与者绑定刚刚注册的数据类型
    this->request_type_ = eprosima::fastdds::dds::TypeSupport(new CommonDataPubSubType());
    this->reply_type_ = eprosima::fastdds::dds::TypeSupport(new CommonDataPubSubType());
    this->participant_->register_type(this->request_type_);
    this->participant_->register_type(this->reply_type_);

    // 让参与者创建消息发送者, 用于发送请求
    this->publisher_= this->participant_->create_publisher(
        eprosima::fastdds::dds::PUBLISHER_QOS_DEFAULT
    );
    if (nullptr == this->publisher_) {
        return false;
    }

    // 让参与者创建消息接收者，用于接收回复
    this->subscriber_ = this->participant_->create_subscriber(
        eprosima::fastdds::dds::SUBSCRIBER_QOS_DEFAULT
    );
    if (nullptr == this->subscriber_) {
        return false;
    }

    // 让参与者创建请求Topic
    this->request_topic_ = this->participant_->create_topic(
        "simple_service/request", this->request_type_.get_type_name(), eprosima::fastdds::dds::TOPIC_QOS_DEFAULT
    );
    if (this->request_topic_ == nullptr){
        return false;
    }

    // 让参与者创建接收 Topic
    this->reply_topic_ = this->participant_->create_topic(
        "simple_service/response", this->reply_type_.get_type_name(), eprosima::fastdds::dds::TOPIC_QOS_DEFAULT
    );
    if (this->request_topic_ == nullptr){
        return false;
    }

    // 让消息发送者创建 data_writer
    this->request_writer_ = this->publisher_->create_datawriter(this->request_topic_, eprosima::fastdds::dds::DATAWRITER_QOS_DEFAULT);
    if (this->request_writer_ == nullptr){
        return false;
    }

    // 让消息接收者创建 data_reader
    eprosima::fastdds::dds::DataReaderQos reader_qos;
    reader_qos.reliability().kind = eprosima::fastdds::dds::RELIABLE_RELIABILITY_QOS;
    reader_qos.history().kind = eprosima::fastdds::dds::KEEP_LAST_HISTORY_QOS;
    this->reply_reader_ = this->subscriber_->create_datareader(this->reply_topic_, reader_qos, &this->_listener);
    if (this->reply_reader_ == nullptr){
        return false;
    }

    // 如果每个步骤都成功，就返回 true
    return true;

}

void BaseClient::deinit()
{
    if (this->participant_ != nullptr){
        this->participant_->delete_contained_entities();
        eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->delete_participant(participant_);
    }
}